//
//  RecordAudio.m
//  JuuJuu
//
//  Created by xiaoguang huang on 11-12-19.
//  Copyright (c) 2011年 __MyCompanyName__. All rights reserved.
//

#import "RecordAudio.h"
#import <AudioToolbox/AudioToolbox.h>
#import <AVFoundation/AVFoundation.h>
#import "amrFileCodec.h"

@implementation RecordAudio


- (void)dealloc {
    [recorder dealloc];
	recorder = nil;
	recordedTmpFile = nil;
    [avPlayer stop];
    [avPlayer release];
    avPlayer = nil;
    [super dealloc];
}

-(id)init {
    self = [super init];
    if (self) {
        //Instanciate an instance of the AVAudioSession object.
        AVAudioSession * audioSession = [AVAudioSession sharedInstance];
        //Setup the audioSession for playback and record. 
        //We could just use record and then switch it to playback leter, but
        //since we are going to do both lets set it up once.
        [audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error: &error];
        
        UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker;
        AudioSessionSetProperty (kAudioSessionProperty_OverrideAudioRoute,
								 sizeof (audioRouteOverride),
								 &audioRouteOverride);
        
        //Activate the session
        [audioSession setActive:YES error: &error];
    }
    return self;
}

#pragma mark -
#pragma mark - Record
-(void) startRecord {
    // if the record is paused, resume the record
    if (recorder) {
        [recorder record];
        return;
    }
    
    
    //Begin the recording session.
    //Error handling removed.  Please add to your own code.
    
    //Setup the dictionary object with all the recording settings that this
    //Recording sessoin will use
    //Its not clear to me which of these are required and which are the bare minimum.
    //This is a good resource: http://www.totodotnet.net/tag/avaudiorecorder/
    
    NSDictionary *recordSetting = [NSDictionary dictionaryWithObjectsAndKeys:
                                   [NSNumber numberWithInt:kAudioFormatLinearPCM], AVFormatIDKey,
                                   [NSNumber numberWithFloat:8000.00], AVSampleRateKey,
                                   [NSNumber numberWithInt:1], AVNumberOfChannelsKey,
                                   [NSNumber numberWithInt:16],AVLinearPCMBitDepthKey,
                                   [NSNumber numberWithBool:NO], AVLinearPCMIsNonInterleaved,
                                   [NSNumber numberWithBool:NO],AVLinearPCMIsFloatKey,
                                   [NSNumber numberWithBool:NO], AVLinearPCMIsBigEndianKey,
                                   nil];
    
    //Now that we have our settings we are going to instanciate an instance of our recorder instance.
    //Generate a temp file for use by the recording.
    //This sample was one I found online and seems to be a good choice for making a tmp file that
    //will not overwrite an existing one.
    //I know this is a mess of collapsed things into 1 call.  I can break it out if need be.
    recordedTmpFile = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent: [NSString stringWithFormat: @"%.0f.%@", [NSDate timeIntervalSinceReferenceDate], @"caf"]]];
    
    //Setup the recorder to use this file and record to it.
    recorder = [[ AVAudioRecorder alloc] initWithURL:recordedTmpFile settings:recordSetting error:&error];
    [recorder setDelegate:self];
    [recorder prepareToRecord];
    [recorder record];
    [self sendRecordStatus:RecordStateStart andAudioUrl:nil];
    //There is an optional method for doing the recording for a limited time see
    //[recorder recordForDuration:(NSTimeInterval) 10]
}
- (NSString *) stopRecord {
    NSURL *url = [[NSURL alloc]initWithString:recorder.url.absoluteString];
    [recorder stop];
    
    // 判断录音时长，不能小于1秒钟
    NSTimeInterval timeInterval = [RecordAudio getAudioTime:[NSData dataWithContentsOfURL:recorder.url]];
    if (timeInterval < 1.0) {
        NSLog(@"录音失败，录音时长不能小于1秒钟，此次录音时长：%f", timeInterval);

        [[NSFileManager defaultManager] removeItemAtURL:url error:&error];
        if (error) {
            NSLog(@"录音失败，移除caf临时文件失败");
        }
        [self sendRecordStatus:RecordStateFail andAudioUrl:nil];
        return nil;
    } else {
        NSData *playData = EncodeWAVEToAMR([NSData dataWithContentsOfURL:recorder.url],1,16);
        
        NSString *amrFileName = [url.absoluteString.lastPathComponent substringToIndex:url.absoluteString.lastPathComponent.length - 4];
        NSString *amrPath = [NSTemporaryDirectory() stringByAppendingString:[NSString stringWithFormat:@"%@.amr", amrFileName]];
        NSLog(@"录音的路径在此:%@", amrPath);
        [playData writeToFile:amrPath options:NSDataWritingAtomic error:&error];
        
        [[NSFileManager defaultManager] removeItemAtURL:url error:&error];
        if (error) {
            NSLog(@"录音成功，移除caf临时文件失败");
        }
        [self sendRecordStatus:RecordStateStop andAudioUrl:amrPath];
        
        [recorder release];
        recorder = nil;
        return amrPath;
    }
}
- (void)pauseRecord {
    [recorder pause];
    [self sendRecordStatus:RecordStatePause andAudioUrl:nil];
}
- (void)cancelRecord {
    [recorder stop];
    [recorder release];
    recorder = nil;
    
    if ([recorder deleteRecording]) {
        NSLog(@"取消录音成功\n");
        [[NSFileManager defaultManager] removeItemAtPath:recorder.url.absoluteString error:nil];
        [self sendRecordStatus:RecordStateCancel andAudioUrl:nil];
        
    } else {
        NSLog(@"取消录音失败\n");
    }
}

+(NSTimeInterval) getAudioTime:(NSData *) data {
    NSError * error;
    AVAudioPlayer*play = [[AVAudioPlayer alloc] initWithData:data error:&error];
    NSTimeInterval n = [play duration];
    [play release];
    return n;
}

-(void)sendRecordStatus:(RecordState)status andAudioUrl:(NSString *)audioUrl {
    
    if ([self.delegate respondsToSelector:@selector(recordResult:andAudioUrlStr:)]) {
        [self.delegate recordResult:status andAudioUrlStr:audioUrl];
    }
}

#pragma mark -
#pragma mark - Play
- (void)sendPlayAudioStatus:(AudioPlayState)status {
    if ([self.delegate respondsToSelector:@selector(audioPlayResult:)]) {
        [self.delegate audioPlayResult:status];
    }
}
- (void)playWithAudioUrlStr:(NSString *)audioUrlStr {
    NSData *audioData = [NSData dataWithContentsOfFile:audioUrlStr];
    [self play:audioData];
}

-(void) play:(NSData*) data{
    //Setup the AVAudioPlayer to play the file that we just recorded.
    //在播放时，只停止
    if (avPlayer!=nil) {
        [self stopPlay];
        return;
    }
    
    NSData* o = [self decodeAmr:data];//decode
    
    avPlayer = [[AVAudioPlayer alloc] initWithData:o error:&error];
    avPlayer.delegate = self;
    [avPlayer prepareToPlay];
    [avPlayer setVolume:1.0];
    if(![avPlayer play]){
        [self sendPlayAudioStatus:AudioPlayStateStart];
    } else {
        [self sendPlayAudioStatus:AudioPlayStateFail];
    }
}
-(void) stopPlay {
    if (avPlayer!=nil) {
        [avPlayer stop];
        [avPlayer release];
        avPlayer = nil;
        [self sendPlayAudioStatus:AudioPlayStateStop];
    }
}
- (void)pausePlay {
    if (avPlayer) {
        [avPlayer pause];
        [self sendPlayAudioStatus:AudioPlayStatePause];
    }
}

-(NSData *)decodeAmr:(NSData *)data{
    if (!data) {
        return data;
    }

    return DecodeAMRToWAVE(data);
}

- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag {
    [avPlayer stop];
    [avPlayer release];
    avPlayer = nil;
    
    [self sendPlayAudioStatus:AudioPlayStateComplete];
}

- (void)audioPlayerDecodeErrorDidOccur:(AVAudioPlayer *)player error:(NSError *)error{
    [avPlayer release];
    avPlayer = nil;
    [self sendPlayAudioStatus:AudioPlayStateFail];
}

@end
